﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.DAL.DocumentCenter;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Linq;
using DTO = MS.InformationManagement.DAL.DTOs;
using Microsoft.SharePoint.Taxonomy;
using MS.InformationManagement.Support.Constants;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.BLL.GlobalCommands;
using MS.InformationManagement.Core.TransactionsResponse;

namespace MS.InformationManagement.BLL.DocumentPrinter
{
    public class DocumentDeliveryConfigBLL
    {

        #region fields

        Queue<ICommand> _transactionCommands;

        #endregion

        public static Radicado GetDocument(int id, string librayName)
        {
            Radicado entity = null;
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                EntityList<Radicado> targetList = ctx.GetList<Radicado>(librayName);
                entity = targetList.SingleOrDefault(rad => rad.Id.Equals(id));
            }

            if (entity == default(Radicado)) { throw new Exception(string.Format("El documento cuyo id es {0} no existe en la biblioteca {1}", id, librayName)); }

            return entity;
        }

        public static IEnumerable<MedioDeEnvio> GetDeliveryMeans()
        {
            IEnumerable<MedioDeEnvio> deliveryMeans = null;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                deliveryMeans = (from deliveryMean in ctx.MediosDeEnvio
                                 select deliveryMean);
            }

            return deliveryMeans;
        }

        public static ConfiguracionDeCostosDeMedioDeEnvio GetDeliveryMeanCost(int deliveryMeanID, double weight)
        {
            ConfiguracionDeCostosDeMedioDeEnvio entity = null;
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                entity = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.Where(
                        config => config.MedioEnvioCostos.Id.Equals(deliveryMeanID)
                            && config.LímiteInferior <= weight && config.LímiteSuperior >= weight
                    ).ToList().SingleOrDefault();
            }
            return entity;
        }

        public void SendMailDelivery(DTO.EnvíoDeCorrespondenciaDTO[] deliveries)
        {

            try
            {
                //Configuring transaction commands
                _transactionCommands = new Queue<ICommand>();

                //Updating document status
                UpdateWeighUpDocumentCommand updateDocuments = new UpdateWeighUpDocumentCommand(deliveries);
                updateDocuments.Execute();
                _transactionCommands.Enqueue(updateDocuments);

                //Update existing deliveries
                UpdateDeliveryMailCommand updateDeliveries = new UpdateDeliveryMailCommand(deliveries);
                UpdateDeliveryCommandResponse newDeliveries = updateDeliveries.Execute() as UpdateDeliveryCommandResponse;
                _transactionCommands.Enqueue(updateDeliveries);

                //Creating new deliveries
                CreateDeliveryMailCommand newDeliveriesCommand = new CreateDeliveryMailCommand(newDeliveries.NewDeliveries.ToArray());
                newDeliveriesCommand.Execute();
                _transactionCommands.Enqueue(newDeliveriesCommand);

            }
            catch (Exception ex)
            {
                undoTransaction();
                throw ex;
            }
        }

        private void undoTransaction()
        {
            foreach (ICommand transaction in _transactionCommands)
                transaction.Undo();
        }

        private static void RemoveDocumentFromPrintedDocuments(string documentNumber, DCDocumentCenterDataContext context)
        {
            DocumentoImpreso entity = context.DocumentosImpresos.SingleOrDefault(printedDoc => printedDoc.NoRadicado.Equals(documentNumber));
            if (entity == default(DocumentoImpreso)) { throw new Exception(string.Format("No existe un registro asociado al documento {0} en la lista de documentos impresos", documentNumber)); }
            context.DocumentosImpresos.RecycleOnSubmit(entity);
        }

        public  void UpdateSendMailDelivery(int documentID, string libraryName, TaxonomyFieldValue city, string address, string email, string phoneNumber)
        {
            try
            {
                _transactionCommands = new Queue<ICommand>();
                
                //Update radicado
                UpdateDeliveryDataRadicadoCommand updateDocumentCommand = new UpdateDeliveryDataRadicadoCommand(libraryName, documentID, email, phoneNumber, address, city);
                updateDocumentCommand.Execute();
                _transactionCommands.Enqueue(updateDocumentCommand);

                //Update delivery list data

                UpdateDeliveryDataCommand updateDeliveryData = new UpdateDeliveryDataCommand(libraryName, documentID, email, phoneNumber, address, city);
                updateDeliveryData.Execute();

            }
            catch(Exception ex)
            {
                undoTransaction();
                throw ex;
            }
        }

    }
}
